/**
  ******************************************************************************
  * @file    TIM1_ComplementarySignals_DeadTime_Break_Lock\main.c
  * @author  MCD Application Team
  * @version  V2.2.0
  * @date     30-September-2014
  * @brief   This file contains the main function for TIM1 Complementary Signals &
  *          DeadTime & Break & Lock.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
#include "qumi_config.h"
#include "temperature.h"
#include "humidity.h"
/*#include "se8r01.h"*/
#include "nrf24.h"
#include "sched.h"
#include "misc.h"
#include "led.h"

/**
  * @addtogroup TIM1_ComplementarySignals_DeadTime_Break_Lock
  * @{
  */

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
//Host:   TX_Addr:0xD7 RX_Addr:0xE7
//client: TX_Addr:0xE7 RX_Addr:0xD7
uint8_t tx_address[NRF24L01_ADDR_LEN] = {NRF24L01_C_TXADDR,NRF24L01_C_TXADDR,NRF24L01_C_TXADDR,NRF24L01_C_TXADDR,NRF24L01_C_TXADDR};
uint8_t rx_address[NRF24L01_ADDR_LEN] = {NRF24L01_C_RXADDR,NRF24L01_C_RXADDR,NRF24L01_C_RXADDR,NRF24L01_C_RXADDR,NRF24L01_C_RXADDR};
uint8_t data_array[NRF24L01_DATA_LEN];
volatile bool     g_adc_finished = FALSE;
/* Private function prototypes -----------------------------------------------*/
void ADC_Init(void);
void GPIO_Cfg(void);
uint32_t LSIMeasurment(void);
void AWU_Config();
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
void main(void)
{

  /* select Clock = 16 MHz */
  CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
 
  AWU_Config();
  
  /*CLK_CCOConfig(CLK_OUTPUT_CPU);*/
#ifdef ENALBE_IWDG
  /* Enable IWDG (the LSI oscillator will be enabled by hardware) */
  IWDG_Enable();
  
  /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency
     dispersion) */
  /* Enable write access to IWDG_PR and IWDG_RLR registers */
  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
   
  /* IWDG counter clock: LSI/128 */
  IWDG_SetPrescaler(IWDG_Prescaler_128);
  
  //Set counter reload value to obtain 1.02s IWDG Timeout
  IWDG_SetReload((uint8_t)(0xFF));
  
  /* Reload IWDG counter */
  IWDG_ReloadCounter();
#endif

  //Init all device
  ADC_Init();
  /*LED_Init();*/
  GPIO_Cfg();
  Temp_Init();
  Humidity_Init();
  /*Se8r01_Init();*/

  //nRF24L01 Init
  nrf24_init();
  /* Channel #2 , payload length: 4 */
  nrf24_config(NRF24L01_CHANNEL, NRF24L01_DATA_LEN);
  /* Set the device addresses */
  nrf24_tx_address(tx_address);
  nrf24_rx_address(rx_address);


  /*Sched_Init();*/
  /*LED_Start(ENABLE);*/

#ifdef ENALBE_IWDG
  IWDG_ReloadCounter();  
#endif

  enableInterrupts();


  while (1)
  {
#ifdef ENALBE_IWDG
    IWDG_ReloadCounter();  
    DelayMS(500);
#endif

    halt();
    Humidity_Start(ENABLE);
    ADC1_Cmd(ENABLE);
    DelayMS(100);
    TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
    while(g_adc_finished == FALSE)
    {
      DelayMS(5);
    }
    g_adc_finished = FALSE;

    //send data to host
    data_array[0] = NRF24L01_SENSOR;
    data_array[1] = g_temp;
    data_array[2] = g_humi;
    data_array[3] = 77;

    /* Automatically goes to TX mode */
    nrf24_send(data_array);       
    DelayMS(10);

    TIM1_ITConfig(TIM1_IT_UPDATE, DISABLE);
    ADC1_Cmd(DISABLE);
    Humidity_Start(DISABLE);
    /*TIM1_DeInit();*/
  }
}

void ADC_Init(void)
{
  //ADC CH2: Humidity
  //ADC CH3: Temperature
  //ADC CH4: Battery
  /* Init ADC1 peripheral */
  ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, BATTERY_CH, ADC1_PRESSEL_FCPU_D2, \
            ADC1_EXTTRIG_TIM, ENABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL4,\
            ENABLE);
  
  ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);
  ADC1_DataBufferCmd(ENABLE);
  ADC1_ScanModeCmd(ENABLE);
  /*ADC1_Cmd(ENABLE);*/
}

/*
 * All GPIO Init here
 */
void GPIO_Cfg(void)
{
#ifdef GPIOA_OUTPUT_PINS
  GPIO_Init(GPIOA, GPIOA_OUTPUT_PINS, GPIO_MODE_OUT_PP_LOW_SLOW);
#endif
#ifdef GPIOA_INPUT_PINS
  GPIO_Init(GPIOA, GPIOA_INPUT_PINS, GPIO_MODE_IN_FL_IT);
#endif
#ifdef GPIOB_OUTPUT_PINS
  GPIO_Init(GPIOB, GPIOB_OUTPUT_PINS, GPIO_MODE_OUT_PP_LOW_SLOW);
#endif
  GPIO_Init(SPI_CS_PORT, SPI_CS_PIN|SPI_MOSI_PIN, GPIO_MODE_OUT_OD_LOW_SLOW);

  GPIO_Init(GPIOC, GPIOC_INPUT_PINS, GPIO_MODE_IN_FL_NO_IT);
  GPIO_Init(GPIOD, GPIOD_OUTPUT_PINS, GPIO_MODE_OUT_PP_LOW_FAST);
  /*  Init GPIO for thermistor */
  GPIO_Init(THERMISTOR_PORT, THERMISTOR_PIN, GPIO_MODE_IN_FL_NO_IT);
}

/**
  * @brief  Measure the LSI frequency using timer IC1 and update the calibration registers.
  * @note   It is recommended to use a timer clock frequency of at least 10MHz in order 
	*         to obtain a better in the LSI frequency measurement.
	* @param  None
  * @retval None
  */
uint32_t LSIMeasurment(void)
{
  
  uint32_t lsi_freq_hz = 0x0;
  uint32_t fmaster = 0x0;
  uint16_t ICValue1 = 0x0;
  uint16_t ICValue2 = 0x0;

  /* Get master frequency */
  fmaster = CLK_GetClockFreq();

  /* Enable the LSI measurement: LSI clock connected to timer Input Capture 1 */
  AWU->CSR |= AWU_CSR_MSR;

#if defined (STM8S903) || defined (STM8S103) || defined (STM8S003)
  /* Measure the LSI frequency with TIMER Input Capture 1 */
  
  /* Capture only every 8 events!!! */
  /* Enable capture of TI1 */
	TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0);
	
  /* Enable TIM1 */
  TIM1_Cmd(ENABLE);
  
  /* wait a capture on cc1 */
  while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
  /* Get CCR1 value*/
  ICValue1 = TIM1_GetCapture1();
  TIM1_ClearFlag(TIM1_FLAG_CC1);
  
  /* wait a capture on cc1 */
  while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
  /* Get CCR1 value*/
  ICValue2 = TIM1_GetCapture1();
  TIM1_ClearFlag(TIM1_FLAG_CC1);
  
  /* Disable IC1 input capture */
  TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E);
  /* Disable timer2 */
  TIM1_Cmd(DISABLE);
  TIM1_DeInit();
  
#else  
  /* Measure the LSI frequency with TIMER Input Capture 1 */
  
  /* Capture only every 8 events!!! */
  /* Enable capture of TI1 */
  TIM3_ICInit(TIM3_CHANNEL_1, TIM3_ICPOLARITY_RISING, TIM3_ICSELECTION_DIRECTTI, TIM3_ICPSC_DIV8, 0);

  /* Enable TIM3 */
  TIM3_Cmd(ENABLE);

	/* wait a capture on cc1 */
  while ((TIM3->SR1 & TIM3_FLAG_CC1) != TIM3_FLAG_CC1);
	/* Get CCR1 value*/
  ICValue1 = TIM3_GetCapture1();
  TIM3_ClearFlag(TIM3_FLAG_CC1);

  /* wait a capture on cc1 */
  while ((TIM3->SR1 & TIM3_FLAG_CC1) != TIM3_FLAG_CC1);
    /* Get CCR1 value*/
  ICValue2 = TIM3_GetCapture1();
	TIM3_ClearFlag(TIM3_FLAG_CC1);

  /* Disable IC1 input capture */
  TIM3->CCER1 &= (uint8_t)(~TIM3_CCER1_CC1E);
  /* Disable timer3 */
  TIM3_Cmd(DISABLE);
  TIM3_DeInit();
#endif /* STM8S903 || STM8S103*/

  /* Compute LSI clock frequency */
  lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);
  
  /* Disable the LSI measurement: LSI clock disconnected from timer Input Capture 1 */
  AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);

 return (lsi_freq_hz);
}

/**
  * @brief  Configure the AWU time base to 12s
  * @param  None
  * @retval None
  */
void AWU_Config(void)
{
    /* Initialization of AWU */
     /* LSI calibration for accurate auto wake up time base*/
    AWU_LSICalibrationConfig(LSIMeasurment());
    
     /* The delay corresponds to the time we will stay in Halt mode */
    AWU_Init(AWU_TIMEBASE_12S);
}

#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
